﻿--[[
   @brief    dirui model
   @author   amadeusyu
   @version  1.0
   @date     2016-03-07
--]]

dirui_model_constant = {
    LOL_GAME_ID = 26;
    WHITELIST_ZONE_ID = 517;
    MXD2_GAME_ID = 509;
    MXD2_GAME_ID_TEST = 10509;
    WHITELIST_ZONE_ID = 517;

    LOL_TIPS_JS = "lol_whitelist_tips";
    LOL_WHITE_LIST_URL = LoadStr("LOL_WHITE_LIST_URL");
    FEATURE_ID = 1015;
}
dirui_model = {

    is_open_by_native = true;

    lol_tips_data = {};
    white_is_in = true;

    ping_value_list = {};

    cur_uin = 0;
    cur_game_id = 0;
    last_game_id = 0;

    dirui_node_info = {};

    all_dir_info_list = {};

    h_index_list = {};  -- 历史大区列表
    h_info_list = {};  -- 历史大区信息

    picked_index_list = {};  -- 推荐大区列表
    picked_info_list = {};  -- 推荐大区信息

    role_info_list = {};  -- 角色信息列表


    isp_list = {};  -- isp列表
    area_list = {};  -- area列表
    zone_list = {};  -- zone列表

    selected_isp_index = 0;  -- 选中的isp index
    selected_area_index = 0;  -- 选中的area index
    selected_zone_index = 0;  -- 选中的zone index

    zone_list_toshow = {};  -- 显示的大区列表
    zone_horz_list_toshow = {}; --纵向显示大区列表 { {zone_list1}, {zone_list2} }
    area_list_toshow = {};  -- 显示的area列表
    isp_list_toshow = {};  -- 显示的isp列表

    dir_tree_height = 0;  -- 保存当前区服节点层次

    show_ping_value = false;

    init = function()
        comm_center.listen_broadcast("i_broadcast_curl_rsp_lol_whitelist", dirui_model.on_lol_white_list);
    end;

    init_data = function()
        dirui_model.all_dir_info_list = {};
        dirui_model.h_index_list = {};
        dirui_model.h_index_list = {};
        dirui_model.picked_index_list = {};
        dirui_model.picked_info_list = {};
        dirui_model.isp_list = {};
        dirui_model.area_list = {};
        dirui_model.zone_list = {};
        dirui_model.selected_isp_index = 0;
        dirui_model.selected_area_index = 0;
        dirui_model.selected_zone_index = 0;
        dirui_model.zone_list_toshow = {};
        dirui_model.area_list_toshow = {};
        dirui_model.isp_list_toshow = {};
        dirui_model.dir_tree_height = 0;
        dirui_model.show_ping_value = false;
    end;

    parse_dir_info_list = function()
        if next(dirui_model.dirui_node_info) == nil then
            base_utility.log("[dirui_model] parse_dir_info_list failed, dirui_node_info is nil");
            return;
        end;
        dirui_model.init_data();
        -- 获得所有节点列表
        if dirui_model.dirui_node_info.nodeInfoSet ~= nil then
            for i =  1, #(dirui_model.dirui_node_info.nodeInfoSet) do
                dirui_model.dirui_node_info.nodeInfoSet[i].idx = i;
                table.insert(dirui_model.all_dir_info_list, dirui_model.dirui_node_info.nodeInfoSet[i]);
            end;
        end;

        -- 初始化数据


        dirui_model.parse_history_list_id();

        dirui_model.init_default_select_index();

        dirui_model.parse_history_list_info();

        -- 初始化角色信息
        dirui_model.parse_role_list_info();

        -- 初始化要显示的列表数据
        dirui_model.init_default_show_list();
    end;

    -- 初始化默认选中的zone\area\isp
    init_default_select_index = function()
        -- 根据历史选区列表，设置默认选中的zone\area\isp
        if #(dirui_model.h_index_list) > 0 then
            dirui_model.set_select_index(dirui_model.h_index_list);
            return;
        end;
        -- 根据推荐选区列表，设置默认选中的zone\area\isp
        if #(dirui_model.picked_index_list) > 0 then
            dirui_model.set_select_index(dirui_model.picked_index_list);
            return;
        end;

        -- 设置默认选中的zone\area\isp
        dirui_model.set_select_index();

    end;

    -- 初始化默认显示列表
    init_default_show_list = function()
        dirui_model.update_isp_list_info();
        dirui_model.update_area_list_info();
        dirui_control.show_horz_zone_list = nil;
        dirui_control.should_show_horz_zone_list();
        dirui_model.update_zone_list_info();
    end;

    
    -- 根据query_index_list设置默认选中的zone\area\isp，如果没有query_index_list，则顺序遍历，设置默认值
    set_select_index = function(query_index_list)
        local has_get_select = false;
        local all_info_list_length = #(dirui_model.all_dir_info_list);
        
        if query_index_list ~= nil then
            local query_index_list_length = #(query_index_list);
            for index = 1, query_index_list_length do
                local zone_index = query_index_list[index];
                if dirui_model.set_selectindex_by_zone_index(zone_index, all_info_list_length) == true then
                    has_get_select = true;
                    break;
                end;
            end;
        end;
        
        if has_get_select == false then
            -- 没有找到默认选中大区，则设置默认的
            for index = 2, all_info_list_length do
                if dirui_model.all_dir_info_list[index].leafNode == true then
                    -- 表示当前是一个zone节点
                    local set_success = dirui_model.set_selectindex_by_zone_index(index, all_info_list_length);
                    if set_success == true then
                        break;
                    end;
                end;
            end;
        end;
    end;

    set_selectindex_by_zone_index = function(zone_index, all_info_list_length)
        local set_success = false;
        if zone_index > 0 and zone_index <= all_info_list_length then
            local zone_parent_index = dirui_model.all_dir_info_list[zone_index].parentInx + 1;
            if zone_parent_index > 0 and zone_parent_index <= all_info_list_length then
                -- 找到合法的默认选中大区
                dirui_model.selected_zone_index = zone_index;
                if zone_parent_index == 1 then
                    -- 没有area和isp
                    dirui_model.selected_area_index = 0;
                    dirui_model.selected_isp_index = 0;
                    dirui_model.dir_tree_height = 1;
                else
                    -- 存在area和isp
                    local isp_index = dirui_model.all_dir_info_list[zone_parent_index].parentInx + 1;
                    if isp_index == 1 then
                        -- 有isp,没有area
                        dirui_model.selected_isp_index = zone_parent_index;
                        dirui_model.selected_area_index = 0;
                        dirui_model.dir_tree_height = 2;
                    else
                        if isp_index > 0 and isp_index <= all_info_list_length then
                            dirui_model.selected_isp_index = isp_index;
                            dirui_model.selected_area_index = zone_parent_index;
                            dirui_model.dir_tree_height = 3;
                        else
                            dirui_model.selected_isp_index = zone_parent_index;
                            dirui_model.dir_tree_height = 2;
                            base_utility.log("[dirui_model]init_default_select_state, get selected_isp_index failed");
                        end;
                        
                    end;
                end;
                set_success = true;
            end;
        end;
        return set_success;
    end;

    -- 解析得到历史/推荐区服index列表
    parse_history_list_id = function()
        -- 获得历史区服index
        if dirui_model.dirui_node_info.historyCount ~= 0 and
                dirui_model.dirui_node_info.historyLogin and
                #(dirui_model.dirui_node_info.historyLogin) > 0 then
            for i = 1 , #(dirui_model.dirui_node_info.historyLogin) do
                table.insert(dirui_model.h_index_list, dirui_model.dirui_node_info.historyLogin[i] + 1);
            end;
        else
            base_utility.log("[dirui_model] get historyLogin list failed");
        end;

        -- 获得推荐服区服index
        if dirui_model.dirui_node_info.pickedServersCount ~= 0 and
                dirui_model.dirui_node_info.pickedServers and
                #(dirui_model.dirui_node_info.pickedServers) > 0 then
            for i = 1 , #(dirui_model.dirui_node_info.pickedServers) do
                table.insert(dirui_model.picked_index_list, dirui_model.dirui_node_info.pickedServers[i] + 1);
            end;
        else
            base_utility.log("[dirui_model] get pickedServers list failed");
        end;
    end;

    -- 解析得到历史/推荐区服待展示信息列表
    parse_history_list_info = function()
        dirui_model.h_info_list = {};
        dirui_model.picked_info_list = {};
        local dir_info_length = #(dirui_model.all_dir_info_list);

        -- 获得历史大区要显示的内容
        local h_list_length = #(dirui_model.h_index_list);
        
        if h_list_length > 0 then
            for i = 1, h_list_length do
                if dirui_model.h_index_list[i] >= 1 and
                        dirui_model.h_index_list[i] <= dir_info_length then
                    local element = dirui_model.all_dir_info_list[dirui_model.h_index_list[i]];
                    if element.parentInx >= 0 and element.parentInx < dir_info_length then
                        -- 这里找到一个合法的历史大区
                        table.insert(dirui_model.h_info_list, dirui_model.generate_node_item(element));
                    end;
                end;
            end;
        end;

        -- 获得推荐大区要显示的内容
        local picked_list_length = #(dirui_model.picked_index_list);
        if picked_list_length > 0 then
            for i = 1, picked_list_length do
                if dirui_model.picked_index_list[i] >= 1 and 
                        dirui_model.picked_index_list[i] <= dir_info_length then
                    local element = dirui_model.all_dir_info_list[dirui_model.picked_index_list[i]];
                    if element.parentInx >= 0 and element.parentInx < dir_info_length then
                        -- 这里找到一个合法的历史大区
                        table.insert(dirui_model.picked_info_list, dirui_model.generate_node_item(element));
                    end;
                end;
            end;
        end;
    end;

    -- 更新history/picked区分信息列表
    update_history_list_info = function()
        dirui_model.h_index_list = {};
        dirui_model.h_info_list = {};
        dirui_model.picked_index_list = {};
        dirui_model.picked_info_list = {};
        dirui_model.parse_history_list_id();
        dirui_model.parse_history_list_info();
    end;
    -- 更新显示的isp列表
    update_isp_list_info = function()
        dirui_model.isp_list = {};
        dirui_model.isp_list_toshow = {};
        dirui_model.generate_isp_list_info();
    end;

    generate_isp_list_info = function()
        -- isp属于root孩子节点，直接生成
        if dirui_model.dir_tree_height > 1 then
            local node_list_len = #(dirui_model.all_dir_info_list);
            if  node_list_len < 1 then
                base_utility.log("[dirui_model]generate_isp_list_info, index is illegal");
                return;
            end;
            if dirui_model.all_dir_info_list[1].childrenCount == 0 or
                    dirui_model.all_dir_info_list[1].childrenInx == nil then
                base_utility.log("[dirui_model]generate_isp_list_info, no children");
                return;
            end;
            -- 生成isp节点
            local children_list = dirui_model.all_dir_info_list[1].childrenInx;
            for i = 1 , #(children_list) do
                local element = dirui_model.all_dir_info_list[children_list[i] + 1];
                if element ~= nil and element.childrenCount > 0 then   -- isp有子节点才加入
                    table.insert(dirui_model.isp_list_toshow, dirui_model.generate_node_item(element));
                end
            end;
        end;
    end;

    -- 更新显示的area列表
    update_area_list_info = function()
        if dirui_model.dir_tree_height > 2 then
            dirui_model.area_list = {};
            dirui_model.area_list_toshow = {};
            dirui_model.generate_area_list_info(dirui_model.selected_isp_index);
        end;
    end;

    generate_area_list_info = function(father_index)
        -- body
        dirui_model.generate_list_info_common(father_index, dirui_model.area_list_toshow);
    end;

    -- 更新显示的zone列表
    update_zone_list_info = function()
        dirui_model.zone_list = {};
        dirui_model.zone_list_toshow = {};
        dirui_model.zone_horz_list_toshow = {};
        if dirui_control.should_show_horz_zone_list() then
            if dirui_model.selected_isp_index ~= 0 then
                for index = 1, #dirui_model.isp_list_toshow do
                    local zlist = {};
                    dirui_model.generate_list_info_common(
                    dirui_model.isp_list_toshow[index].index, zlist);
                    table.insert(dirui_model.zone_horz_list_toshow, zlist);
                    local zlist_dup = zlist;
                    local zlist_count = #zlist_dup;
                    if zlist_count > 0 and zlist_count < 4 then
                        local zlist_dummy = {};
                        zlist_dup = zlist_dummy;
                        for i = 1, zlist_count do
                            table.insert(zlist_dup, zlist[i]);
                        end
                        local padding_count = 4 - zlist_count;
                        for i = 1, padding_count do
                            table.insert(zlist_dup, zlist[1]);
                        end
                    end
                    for i = 1, #zlist_dup do
                        table.insert(dirui_model.zone_list_toshow, zlist_dup[i]);
                    end
                end
            else
                dirui_model.generate_zone_list_info(1);
                table.insert(dirui_model.zone_horz_list_toshow, dirui_model.zone_list_toshow);
            end
        end

        if #dirui_model.zone_horz_list_toshow > 0 then
            return;
        end

        if dirui_model.selected_area_index ~= 0 then
            -- 点击的是area
            dirui_model.generate_zone_list_info(dirui_model.selected_area_index);
        elseif dirui_model.selected_isp_index ~= 0 then
            -- 没有area,点击的是isp
            dirui_model.generate_zone_list_info(dirui_model.selected_isp_index);
        else
            -- 没有area和isp,则根据root节点生成zone列表
            dirui_model.generate_zone_list_info(1);
        end;
    end;

    -- 生成要显示的zone列表
    generate_zone_list_info = function (father_index)
        dirui_model.generate_list_info_common(father_index, dirui_model.zone_list_toshow);
    end;

    -- 通用生成孩子节点信息
    generate_list_info_common = function (father_index, save_list)
        local node_list_len = #(dirui_model.all_dir_info_list);
        if father_index < 1 or father_index > node_list_len then
            base_utility.log("[dirui_model]generate_list_info_common, father_index is illegal");
            return;
        end;
        if dirui_model.all_dir_info_list[father_index].childrenCount == 0 or
                dirui_model.all_dir_info_list[father_index].childrenInx == nil then
            base_utility.log("[dirui_model]generate_list_info_common, father_index has no children");
            return;
        end;
        -- 生成zone节点
        local children_list = dirui_model.all_dir_info_list[father_index].childrenInx;
        for i = 1 , #(children_list) do
            local element = dirui_model.all_dir_info_list[children_list[i] + 1];
            table.insert(save_list, dirui_model.generate_node_item(element));
        end;
    end;

    -- 生成节点node_element的待显示信息
    generate_node_item = function(node_element)
        if node_element == nil then
            base_utility.log("[dirui_model]generate_node_item, node_element is nil");
            return;
        end;
        local node_item = {};
        node_item.index = node_element.idx;
        node_item.zone_id = node_element.serverID;
        node_item.title = node_element.title;
        if node_element.hotNode then
            node_item.hot_flag = 1;
        else
            node_item.hot_flag = 0;
        end;
        if node_element.pickedNode then
            node_item.picked_flag = 1;
        else
            node_item.picked_flag = 0;
        end;
        if node_element.newNode then
            node_item.new_flag = 1;
        else
            node_item.new_flag = 0;
        end;
        -- 设置节点类型 isp/area/zone, status
        if node_element.parentInx == 0 and not node_element.leafNode then
            node_item.type = "isp";
            node_item.server_status = node_element.status;
        elseif node_element.leafNode == true then
            node_item.type = "zone";
            node_item.server_status = node_element.status;
        else
            node_item.type = "area";
            node_item.server_status = -1;
        end;

        -- 设置是否加锁(lol定制)
        if dirui_model.cur_game_id == dirui_model_constant.LOL_GAME_ID and
                node_element.serverID == dirui_model_constant.WHITELIST_ZONE_ID and
                dirui_model.lol_tips_data.open_whitelist == "1" then
            if dirui_model.white_is_in == true then
                node_item.is_lock = true;
            else
                node_item.is_lock = false;
            end;
        else
            node_item.is_lock = false;
        end;
        -- 设置ping值(冒险岛2)
        node_item.ping_value = 0;

        -- 设置当前的选中态
        if node_item.type == "zone" then
            if node_item.index == dirui_model.selected_zone_index then
                node_item.is_selected = true;
            else
                node_item.is_selected = false;
            end;
        elseif node_item.type == "area" then
            if node_item.index == dirui_model.selected_area_index then
                node_item.is_selected = true;
            else
                node_item.is_selected = false;
            end;
        elseif node_item.type == "isp" then
            if node_item.index == dirui_model.selected_isp_index then
                node_item.is_selected = true;
            else
                node_item.is_selected = false;
            end;
        end;

        return node_item;
    end;

    -- 解析得到角色信息列表
    parse_role_list_info = function()
        dirui_model.role_info_list = {};
        if dirui_model.dirui_node_info.roleInfoCount ~= 0 and
                dirui_model.dirui_node_info.roleInfoSet and
                #(dirui_model.dirui_node_info.roleInfoSet) > 0 then
            for i = 1 , #(dirui_model.dirui_node_info.roleInfoSet) do
                if dirui_model.dirui_node_info.roleInfoSet[i].roleName and dirui_model.dirui_node_info.roleInfoSet[i].roleName ~= "" then
                    table.insert(dirui_model.role_info_list, dirui_model.dirui_node_info.roleInfoSet[i]);
                end;
            end;
        else
            base_utility.log("[dirui_model] no role info");
        end;
    end;

    -- lol 灰度大区 oss相关 begin
    req_lol_oss_tips = function()
        base_utility.curl_request_async(LoadStr("LOL_WHITELIST_TIPS_URL"),
                                       "dirui_model.on_lol_oss_tips",
                                        true, nil, true);
    end;

    on_lol_oss_tips = function(result)
        local ret, ret_table = base_utility.oss_string_to_table(result, "lol_whitelist_tips");
        if nil == ret_table then
            base_utility.log("[dirui_model] get lol tips oss config failed");
            -- 请求大区信息
            dirui_control.req_dir_by_game_id(dirui_model.cur_game_id);
            return;
        end;

        local z_data = ret_table["data"];
        if (nil == z_data) then
            base_utility.log("[dirui_model] get lol tips oss config failed");
            -- 请求大区信息
            dirui_control.req_dir_by_game_id(dirui_model.cur_game_id);
            return;
        end;

        base_utility.log("[dirui_model] get lol tips oss successed");

        -- 解析oss数据，得到已注册的tips_id
        for index = 1, #(z_data) do
            z_data[index].game_id = tonumber(z_data[index].game_id);
            if z_data[index].game_id == dirui_model.cur_game_id then
                dirui_model.lol_tips_data = z_data[index];
                break;
            end;
        end;
        if dirui_model.lol_tips_data.open_whitelist == "1" then
            -- 开启白名单功能，请求白名单
            local req_url = dirui_model_constant.LOL_WHITE_LIST_URL;
            dirui_model.req_lol_white_list(req_url);
        else
            -- 白名单功能被关闭
            -- 请求大区信息
            dirui_control.req_dir_by_game_id(dirui_model.cur_game_id);
         end;

    end;

    req_lol_white_list = function(req_url)
        -- 加登录态
        local req_url_with_data = req_url .."?gameid="..tostring(dirui_model.cur_game_id)
                                  .. "&GameID64="..tostring(dirui_model.cur_game_id).."&biz=5";
        local req_data = {};
        req_data.req_url = req_url_with_data;
        req_data.req_uin = tostring(dirui_model.cur_uin);
        comm_center.call_service("srv_curl_req_lol_whitelist", req_data);
        
        -- local login_req_url = web_utility.make_login_status_url(req_url, dirui_model.cur_uin);
        -- login_req_url = login_req_url.."&gameid="..dirui_model.cur_game_id.."&biz=5";
        -- local user_data = {};
        -- -- 发起请求
        -- base_utility.curl_request_async(login_req_url, 
        --   "dirui_model.on_lol_white_list", true,
        --   nil, base_utility.table_to_json(user_data));
    end;

    on_lol_white_list = function(ret_json)
        if ret_json == nil then
            base_utility.log("[dirui_model]on_lol_white_list, ret ret_json is nil");
            dirui_control.req_dir_by_game_id(dirui_model.cur_game_id);
            return;
        end;
        local ret_json_s = ret_json.rsp_json_s;
        if ret_json_s == nil or ret_json_s == "" then
            base_utility.log("[dirui_model]on_lol_white_list, ret ret_json_s is nil");
            dirui_control.req_dir_by_game_id(dirui_model.cur_game_id);
            return;
        end;
        local ret_table = base_utility.json_to_table(ret_json_s);
        if ret_table and ret_table.Ret and ret_table.Ret == 1 then
            dirui_model.white_is_in = false;
        else
            dirui_model.white_is_in = true;
        end;
        -- 请求大区信息
        dirui_control.req_dir_by_game_id(dirui_model.cur_game_id);
    end;
    -- lol 灰度大区 oss相关 begin
}

dirui_model.init();